package com.songlanyun.modules.comment.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.songlanyun.common.enums.CommentConstant;
import com.songlanyun.common.enums.OpusConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.account.entity.UserInfoEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserInfoService;
import com.songlanyun.modules.article.entity.Article;
import com.songlanyun.modules.article.service.ArticleService;
import com.songlanyun.modules.comment.dao.UserCommentDao;
import com.songlanyun.modules.comment.entity.UserComment;
import com.songlanyun.modules.comment.model.vo.CommentVO;
import com.songlanyun.modules.comment.service.UserCommentService;
import com.songlanyun.modules.exception.MemberException;
import com.songlanyun.modules.opus.entity.Opus;
import com.songlanyun.modules.opus.service.OpusService;
import com.songlanyun.modules.share.entity.ShareRecord;
import org.springframework.stereotype.Service;

import java.lang.reflect.Member;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("userCommentService")
public class UserCommentServiceImpl extends ServiceImpl<UserCommentDao, UserComment> implements UserCommentService {

    @Resource
    private AccountService accountService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private OpusService opusService;

    @Resource
    private ArticleService articleService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserComment> page = this.baseMapper.commentPage(new Query<UserComment>().getPage(params), params);
        page.getRecords().forEach(UserComment::loadTitle);
        return new PageUtils(page);
    }

    @Override
    public PageUtils commentPage(Map<String, Object> params) {
        IPage<UserComment> page = this.baseMapper.commentPage(new Query<UserComment>().getPage(params), params);
        return new PageUtils(page);
    }

    @Override
    public UserComment getById(Long id, boolean isThrow) {
        UserComment userComment = this.baseMapper.selectById(id);
        if (userComment == null && isThrow) {
            throw new RRException(MemberException.COMMENT_NOT_EXISTS);
        }
        return userComment;
    }

    @Override
    public List<UserComment> listByOpusId(Long id, CommentConstant.CommentModelType modelType) {
        List<UserComment> list = this.baseMapper.selectList(
                new LambdaQueryWrapper<UserComment>()
                        .eq(UserComment::getIsShow, true)
                        .eq(UserComment::getModelType, modelType)
                        .eq(UserComment::getModelId, id)
                        .orderByDesc(UserComment::getCreateTime)
        );

        list.forEach(u -> {
            u.setMobile(accountService.getMobileByUserId(u.getCommentUserId()));
            UserInfoEntity userInfo = userInfoService.getById(u.getCommentUserId());
            if (userInfo != null) {
                u.setNickname(userInfo.loadResRealName());
                u.setHeadPhoto(userInfo.getHeadPhoto());
            }
        });

        return list;
    }

    @Override
    public PageUtils opusCommentPage(Map<String, Object> params) {
        //查询作品评价列表
        params.put("model_type", CommentConstant.CommentModelType.OPUS.getCode());
        return this.commentPage(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void show(UserComment userComment) {
        UserComment comment = this.getById(userComment.getId(), true);
        comment.setIsShow(userComment.getIsShow());
        this.baseMapper.updateById(comment);

        //显示隐藏增加评论总数
        switch (comment.getModelType()) {
            case OPUS:
                Opus opus = opusService.getById(comment.getModelId(), true);
                opus.setCommentSum(comment.getIsShow() ? opus.getCommentSum() + 1 : (opus.getCommentSum() - 1 > 0 ? opus.getCommentSum() : 0));
                opusService.updateById(opus);
                break;
            case ARTICLE:
                Article article = articleService.getById(comment.getModelId(), true);
                article.setCommentSum(comment.getIsShow() ? article.getCommentSum() + 1 : (Math.max(article.getCommentSum() - 1, 0)));
                articleService.updateById(article);
                break;
            case OTHER:
            default:
                break;
        }

    }

    @Override
    public Boolean comment(UserComment userComment) {
        //是否评论过
        Boolean b = ifComment(OpusConstant.ModelType.ARTICLE, userComment.getModelId(), userComment.getCommentUserId());
        userComment.filterContent();//过滤敏感词
        //保存评论记录
        this.baseMapper.insert(userComment);
        return b;
    }

    @Override
    public Boolean ifComment(OpusConstant.ModelType modelType, Long modelId, Long commentUserId) {
        CommentConstant.CommentModelType commentModelType = CommentConstant.CommentModelType.getByCode(modelType.getCode());
        Integer count = this.baseMapper.selectCount(
                new LambdaQueryWrapper<UserComment>()
                        .eq(UserComment::getModelType, commentModelType)
                        .eq(UserComment::getModelId, modelId)
                        .eq(UserComment::getModelExist, true)
                        .eq(UserComment::getCommentUserId, commentUserId)
        );
        return count <= 0;
    }

    @Override
    public PageUtils myPage(Map<String, Object> params) {
        IPage<CommentVO> page = this.baseMapper.myPage(new Query<CommentVO>().getPage(params), params);
        return new PageUtils(page);
    }

    @Override
    public Integer commentSum(Long userId) {
        return this.baseMapper.commentSum(userId);
    }

    @Override
    public void modelDel(CommentConstant.CommentModelType modelType, Long modelId) {
        this.update(
                new LambdaUpdateWrapper<UserComment>()
                        .eq(UserComment::getModelType, modelType)
                        .eq(UserComment::getModelId, modelId)
                        .set(UserComment::getModelExist, false)
        );
    }

    @Override
    public PageUtils findList(Map<String, Object> params) {
        IPage<UserComment> page = this.page(
                new Query<UserComment>().getPage(params),
                new LambdaQueryWrapper<UserComment>()
                        .eq(UserComment::getModelExist, true)
                        .orderByDesc(UserComment::getCreateTime)
        );

        return new PageUtils(page);
    }

}
